package de.cbf.cam.dsa.dataprovider.maneuvers;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.runtime.Plugin;
import org.osgi.framework.BundleContext;

import de.cbf.cam.dsa.model.entities.constants.ActionConstants;
import de.cbf.cam.dsa.model.entities.constants.ManeuverConstants;
import de.cbf.cam.dsa.model.entities.constants.SFConstants;
import de.cbf.cam.dsa.model.entities.maneuvers.ManeuverDesc;
import de.cbf.cam.dsa.model.entities.maneuvers.OneManeuver;
import de.cbf.cam.dsa.model.interfaces.IDataProviderManeuver;
import de.cbf.cam.dsa.model.prerequisites.SfPrereq;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator extends Plugin implements IDataProviderManeuver{

	// The plug-in ID
	public static final String PLUGIN_ID = "de.cbf.cam.dsa.dataProvider.maneuvers";

	// The shared instance
	private static Activator plugin;
	
	/**
	 * The constructor
	 */
	public Activator() {
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.runtime.Plugins#start(org.osgi.framework.BundleContext)
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
	}

	/*
	 * (non-Javadoc)
	 * @see org.eclipse.core.runtime.Plugin#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	/**
	 * Returns the shared instance
	 *
	 * @return the shared instance
	 */
	public static Activator getDefault() {
		return plugin;
	}

	private final String name = "ManeuverProvider";
	
	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.model.interfaces.IDataProviderManeuver#getName()
	 */
	@Override
	public String getName() {
		return name;
	}

	/* (non-Javadoc)
	 * @see de.cbf.cam.dsa.model.interfaces.IDataProviderManeuver#provideManeuvers()
	 */
	@Override
	public List<OneManeuver> provideManeuvers() {
		List<OneManeuver> resultList = new ArrayList<OneManeuver>();
		
		resultList.addAll(provideRegisteredManouvers());
		
		return resultList;
	}

	public List<OneManeuver> provideRegisteredManouvers() {
		List<OneManeuver> maneuvers = new ArrayList<OneManeuver>();
		List<String> excludedAttack = new ArrayList<String>();
		List<String> excludedDefense = new ArrayList<String>();
		OneManeuver maneuver;
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_AngriffHaupt);		
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_AngriffDistanz);
		excludedAttack.add(ManeuverConstants.AT_AngriffZweit);
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new AngriffHauptResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Wuchtschlag);		
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Wuchtschlag_Improvisiert);
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Wuchtschlag_Improvisiert);	
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Wuchtschlag);
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Finte);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Finte_Improvisiert);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);	
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Befreiungsschlag);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(4);	
		maneuver.setMaxAttackModifier(4);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Hammerschlag);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(8);	
		maneuver.setMaxAttackModifier(8);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Niederwerfen);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(8);	
		maneuver.setMaxAttackModifier(8);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Schildspalter);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(8);	
		maneuver.setMaxAttackModifier(8);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.AT_Sturmangriff);
		maneuver.setManeuverType(ManeuverConstants.TYPE_AT);
		excludedAttack.clear();
		excludedAttack.add(ManeuverConstants.AT_Finte);
		excludedAttack.add(ManeuverConstants.AT_Finte_Improvisiert);		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(8);	
		maneuver.setMaxAttackModifier(8);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.REA_Ausweichen);
		maneuver.setManeuverType(ManeuverConstants.TYPE_PA);
		excludedAttack.clear();		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		excludedDefense.add(ManeuverConstants.REA_Ausweichen_Gezielt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Haupt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Schild);
		excludedDefense.add(ManeuverConstants.REA_Parade_Zweitwaffe);
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(-1);	
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.REA_Ausweichen_Gezielt);
		maneuver.setManeuverType(ManeuverConstants.TYPE_PA);
		excludedAttack.clear();		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		excludedDefense.add(ManeuverConstants.REA_Ausweichen);
		excludedDefense.add(ManeuverConstants.REA_Parade_Haupt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Schild);
		excludedDefense.add(ManeuverConstants.REA_Parade_Zweitwaffe);
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.REA_Parade_Haupt);
		maneuver.setManeuverType(ManeuverConstants.TYPE_PA);
		excludedAttack.clear();		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		excludedDefense.add(ManeuverConstants.REA_Ausweichen);
		excludedDefense.add(ManeuverConstants.REA_Ausweichen_Gezielt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Schild);
		excludedDefense.add(ManeuverConstants.REA_Parade_Zweitwaffe);
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(-1);	
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.REA_Parade_Zweitwaffe);
		maneuver.setManeuverType(ManeuverConstants.TYPE_PA);
		excludedAttack.clear();		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		excludedDefense.add(ManeuverConstants.REA_Ausweichen);
		excludedDefense.add(ManeuverConstants.REA_Ausweichen_Gezielt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Schild);
		excludedDefense.add(ManeuverConstants.REA_Parade_Haupt);
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(-1);
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		maneuver = new OneManeuver();
		maneuver.setManeuverName(ManeuverConstants.REA_Windmuehle);
		maneuver.setManeuverType(ManeuverConstants.TYPE_PA);
		excludedAttack.clear();		
		maneuver.setExclAtMan(excludedAttack);		
		excludedDefense.clear();
		excludedDefense.add(ManeuverConstants.REA_Ausweichen);
		excludedDefense.add(ManeuverConstants.REA_Parade_Haupt);
		excludedDefense.add(ManeuverConstants.REA_Parade_Schild);
		excludedDefense.add(ManeuverConstants.REA_Parade_Zweitwaffe);
		maneuver.setExclDefMan(excludedDefense);		
		maneuver.setMinModifier(1);		
		maneuver.setResolver(new DummyResolver());
		maneuvers.add(maneuver);
		
		return maneuvers;
	}

	@Override
	public List<ManeuverDesc> provideManeuverDescs() {
		List<ManeuverDesc> descriptions = new ArrayList<ManeuverDesc>();
		ManeuverDesc desc;
		//w/o prereqs
		desc = new ManeuverDesc(ManeuverConstants.REA_Ausweichen);
			desc.getPossibleInActionTypes().add(ActionConstants.FREE_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
			desc = new ManeuverDesc(ManeuverConstants.AT_AngriffHaupt);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);			
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.REA_Parade_Haupt);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Wuchtschlag_Improvisiert);			
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Finte_Improvisiert);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		// w/ prereq
		desc = new ManeuverDesc(ManeuverConstants.REA_Ausweichen_Gezielt);		
			desc.addPrerequisite(new SfPrereq(SFConstants.Ausweichen_I));
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Befreiungsschlag);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);			
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Finte);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Hammerschlag);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);			
		descriptions.add(desc);		
		desc = new ManeuverDesc(ManeuverConstants.AT_Niederwerfen);		
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Sturmangriff);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);		
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Schildspalter);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.AT_Wuchtschlag);
			desc.getPossibleInActionTypes().add(ActionConstants.ATTACK_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);		
		desc = new ManeuverDesc(ManeuverConstants.REA_Parade_Zweitwaffe);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.REA_Parade_Parry);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.REA_Parade_Schild);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);
			desc.getPossibleInActionTypes().add(ActionConstants.ADDITIONAL_ACTION);
		descriptions.add(desc);	
		desc = new ManeuverDesc(ManeuverConstants.REA_Windmuehle);
			desc.getPossibleInActionTypes().add(ActionConstants.DEFEND_ACTION);		
		descriptions.add(desc);	
		return descriptions;
	}
}
